﻿using Common;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;

namespace Linguist.Acoustic.Tiedstate
{
    /// <summary>
    /// Contains an ordered list of senones.
    /// </summary>
    public class SenoneSequence: ISerializable
    {
        private ISenone[] senones;


        /**
        /// a factory method that creates a SeononeSequence from a list of senones.
         *
        /// @param senoneList the list of senones
        /// @return a composite senone
         */
        public static SenoneSequence create(List<CompositeSenone> senoneList) 
        {
            return new SenoneSequence(senoneList.ToArray());
        }


        /**
        /// Constructs a senone sequence
         *
        /// @param sequence the ordered set of senones for this sequence
         */
        public SenoneSequence(ISenone[] sequence) 
        {
            this.senones = sequence;
        }


        /**
        /// Returns the ordered set of senones for this sequence
         *
        /// @return the ordered set of senones for this sequence
         */
        public ISenone[] getSenones() 
        {
            return senones;
        }


        /**
        /// Returns the hashCode for this object
         *
        /// @return the object hashcode
         */
        public int hashCode() 
        {
            int hashCode = 31;
            foreach (ISenone senone in senones) 
            {
                hashCode = hashCode* 91 + senone.GetHashCode();
            }
            return hashCode;
        }


        /**
        /// Returns true if the objects are equal
         *
        /// @return true  if the objects are equal
         */

        public Boolean Equals(Object o) 
        {
            if (this == o) {
                return true;
            } 
            else 
            {
                if (o is SenoneSequence) 
                {
                    SenoneSequence other = (SenoneSequence) o;
                    if (senones.Length != other.senones.Length) 
                    {
                        return false;
                    } 
                    else 
                    {
                        for (int i = 0; i < senones.Length; i++) 
                        {
                            if (!senones[i].Equals(other.senones[i])) 
                            {
                                return false;
                            }
                        }
                        return true;
                    }
                }
                return false;
            }
        }


        /**
        /// Dumps this senone sequence
         *
        /// @param msg a string annotation
         */
        public void dump(String msg) 
        {
            Trace.WriteLine(" SenoneSequence " + msg + ':');
            foreach (ISenone senone in senones) 
            {
                senone.dump("  seq:");
            }
        }

        void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
        {
            throw new NotImplementedException();
        }
    }
}
